/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package be.ugent.medirem.persistence.facade;

import be.ugent.medirem.persistence.entity.Consultation;
import be.ugent.medirem.persistence.entity.GeneralPractitioner;
import be.ugent.medirem.persistence.entity.Patient;
import be.ugent.medirem.persistence.entity.details.ConsultationDetails;
import be.ugent.medirem.persistence.entity.values.ConsultationValues;
import be.ugent.medirem.persistence.util.EntityDetailsToEntity;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import javax.ejb.EJBException;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.EntityNotFoundException;
import javax.persistence.PersistenceContext;

/**
 *
 * @author Simon
 */
@Stateless
public class ConsultationDaoBean implements ConsultationDaoLocal {

    @PersistenceContext
    private EntityManager em;
    
    public Long create(ConsultationValues c) throws EntityNotFoundException, IllegalArgumentException {
        if (c.getPatientId() == null)
            throw new IllegalArgumentException("PatientId can't be null.");
        if (c.getGpId() == null)
            throw new IllegalArgumentException("GpId can't be null.");
        if (c.getDate() == null)
            throw new IllegalArgumentException("Date can't be null.");

        try {
            GeneralPractitioner gp = em.find(GeneralPractitioner.class, c.getGpId());
            Patient p = em.find(Patient.class, c.getPatientId());
            if (gp == null)
                throw new EntityNotFoundException(this.toString() + " Could not find a gp with id " + c.getGpId());
            if (p == null)
                throw new EntityNotFoundException(this.toString() + " Could not find a patient with id " + c.getGpId());
            Consultation consultation = new Consultation(gp, p, c.getDate());
            em.persist(consultation);
            return consultation.getId();
        } catch (Exception e) {
            throw new EJBException(e);
        }
    }

    public ConsultationDetails getDetails(Long id) throws IllegalArgumentException, EntityNotFoundException {
        if (id == null)
            throw new IllegalArgumentException("Id can't be null.");

        try {
            Consultation c = em.find(Consultation.class, id);
            if (c == null)
                throw new EntityNotFoundException(this.toString() + " Could not find a consultation with id " + id);
            return EntityDetailsToEntity.detailsToConsultation(c);
        } catch (Exception e) {
            throw new EJBException(e);
        }
    }

    public List<ConsultationDetails> getGpConsultations(Long gpId) throws IllegalArgumentException, EntityNotFoundException {
        if (gpId == null)
            throw new IllegalArgumentException("GpId can't be null.");

        try {
            List<Consultation> list = em.createNamedQuery("Consultation.findByGp").setParameter("gp", gpId).getResultList();
            List<ConsultationDetails> l = new ArrayList<ConsultationDetails>();
            for (Consultation c : list)
                l.add(EntityDetailsToEntity.detailsToConsultation(c));
            return l;
        } catch (Exception e) {
            throw new EJBException(e);
        }
    }

    public List<ConsultationDetails> getPatientConsultations(Long patientId) throws IllegalArgumentException, EntityNotFoundException {
        if (patientId == null)
            throw new IllegalArgumentException("PatientId can't be null.");

        try {
            List<Consultation> list = em.createNamedQuery("Consultation.findByPatient").setParameter("patient", patientId).getResultList();
            List<ConsultationDetails> l = new ArrayList<ConsultationDetails>();
            for (Consultation c : list)
                l.add(EntityDetailsToEntity.detailsToConsultation(c));
            return l;
        } catch (Exception e) {
            throw new EJBException(e);
        }
    }

    public ConsultationDetails getNextConsultation(Long gpId, Long patientId) throws EntityNotFoundException, IllegalArgumentException {
        if (gpId == null)
            throw new IllegalArgumentException("GpId can't be null.");
        if (patientId == null)
            throw new IllegalArgumentException("PatientId can't be null.");


        try {
            List<Consultation> list = em.createNamedQuery("Consultation.findConsultationsFromPatientWithGp")
                    .setParameter("gp", gpId)
                    .setParameter("patient", patientId)
                    .getResultList();
            if (list.isEmpty())
                return null;
            Calendar calendar = Calendar.getInstance();
            Consultation c = null;
            for (Consultation con : list) {
                if (con.getDate().after(calendar.getTime())) {
                    if (c == null || con.getDate().before(c.getDate())) {
                        c = con;
                    }
                }
            }
            if (c == null || c.getDate().before(calendar.getTime()))
                return null;
            return new ConsultationDetails(c.getId(), gpId, patientId, c.getDate());
        } catch (Exception e) {
            throw new EJBException(e);
        }

    }

    public ConsultationDetails getPreviousConsultation(Long gpId, Long patientId) throws EntityNotFoundException, IllegalArgumentException {
        if (gpId == null)
            throw new IllegalArgumentException("GpId can't be null.");
        if (patientId == null)
            throw new IllegalArgumentException("PatientId can't be null.");


        try {
            List<Consultation> list = em.createNamedQuery("Consultation.findConsultationsFromPatientWithGp")
                    .setParameter("gp", gpId)
                    .setParameter("patient", patientId)
                    .getResultList();
            if (list.isEmpty())
                return null;
            Calendar calendar = Calendar.getInstance();
            calendar.set(Calendar.HOUR, 0);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
            Consultation c = null;
            for (Consultation con : list) {
                if (con.getDate().before(calendar.getTime()))
                    if (c == null || con.getDate().after(c.getDate()))
                        c = con;
            }
            if (c == null || c.getDate().after(calendar.getTime()))
                return null;
            return new ConsultationDetails(c.getId(), gpId, patientId, c.getDate());
        } catch (Exception e) {
            throw new EJBException(e);
        }

    }


}
